import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

@SuppressWarnings("serial")
public class Funktsioon extends JPanel {

	static JLabel tekst;
	static JLabel tekst2, manuaal;
	static JTextField vali;
	static JTextArea juhend;
	static String message, sisend;
	static ArrayList<String> sisendid;
	static ArrayList<Funktsioon_Abi> funktsioonid;
	static Color[] v2rvid = new Color[] { Color.BLUE, Color.RED, Color.BLACK,
			Color.GREEN, Color.YELLOW, Color.MAGENTA, Color.ORANGE, Color.PINK,
			Color.CYAN, Color.LIGHT_GRAY };

	static Funktsioon_Abi mate;
	static boolean toimib = false;
	static int X_koord, Y_koord, X_nihe, Y_nihe, X_last, Y_last;
	static double suurus = 1.0;

	public Funktsioon() {
		setLayout(new BorderLayout());
		setBackground(Color.WHITE);

		sisendid = new ArrayList<String>();
		funktsioonid = new ArrayList<Funktsioon_Abi>();

		tekst = new JLabel("  Sisesta funktsioon ja vajuta enterit");
		tekst.setForeground(Color.RED);
		tekst.setBorder(BorderFactory.createLineBorder(Color.GRAY, 5));
		this.add(tekst, BorderLayout.NORTH);

		Joonis graafik = new Joonis();

		this.add(graafik, BorderLayout.CENTER);

		JPanel kolmas = new JPanel();
		kolmas.setLayout(new BorderLayout());
		tekst2 = new JLabel("  f(x) = ");
		vali = new JTextField(10);
		vali.addActionListener(graafik);
		kolmas.add(tekst2, BorderLayout.WEST);
		kolmas.add(vali, BorderLayout.CENTER);
		kolmas.setBorder(BorderFactory.createLineBorder(Color.GRAY, 5));
		this.add(kolmas, BorderLayout.SOUTH);

		JPanel neljas = new JPanel();
		neljas.setLayout(new BorderLayout());
		manuaal = new JLabel("MANUAAL");
		JPanel viies = new JPanel();
		viies.setLayout(new FlowLayout());
		viies.add(manuaal);
		juhend = new JTextArea(
				"Funktsioon tuleb sisestada kujul: *sin(3*x)+4 \n*3^2+x \n*log2(x)"
						+ "+x \n*cos(x)+2^x-3 \n\n\nMaksimum\n10 funktsiooni.\n\nKasuta\nhiireklahve\nzoomimiseks.");
		juhend.setEditable(false);
		juhend.setBorder(BorderFactory.createMatteBorder(2, 4, 2, 2,
				Color.BLACK));
		juhend.setBackground(Color.LIGHT_GRAY);
		juhend.setLineWrap(true);
		JButton nullija = new JButton("Nulli kõik");
		nullija.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				sisendid = new ArrayList<String>();
				funktsioonid = new ArrayList<Funktsioon_Abi>();
				toimib = false;
				suurus = 1.0;
				repaint();
			}
		});
		neljas.add(viies, BorderLayout.NORTH);
		neljas.add(juhend, BorderLayout.CENTER);
		neljas.add(nullija, BorderLayout.SOUTH);
		this.add(neljas, BorderLayout.EAST);
	}

	public static class Joonis extends JPanel implements ActionListener {
		
		public Joonis() {
			
			this.addMouseMotionListener(new MouseMotionListener() {				
				
				public void mouseDragged(MouseEvent e) {
					
					X_koord = e.getX();
					Y_koord = e.getY();
					X_nihe = X_nihe+X_koord-X_last;
					Y_nihe = Y_nihe+Y_koord-Y_last;
					X_last = X_koord;
					Y_last = Y_koord;
					repaint();
				}

				public void mouseMoved(MouseEvent e) {
					X_koord = e.getX();
					Y_koord = e.getY();
					X_last = X_koord;
					Y_last = Y_koord;
					repaint();
				}

			});

			this.addMouseListener(new MouseListener() {
				public void mouseClicked(MouseEvent klikats) {
					if (klikats.isMetaDown()) {
						suurus = suurus / 2.;
					} else {
						suurus = suurus * 2.0;
					}
					repaint();
				}

				public void mouseEntered(MouseEvent e) {
				}

				public void mouseExited(MouseEvent e) {
				}

				public void mousePressed(MouseEvent e) {
				}

				public void mouseReleased(MouseEvent klikats) {
				}

			});

		}

		public void paintComponent(Graphics g) {
			super.paintComponent(g);
			setBackground(Color.WHITE);
			int w = getWidth();
			int h = getHeight();
			if (toimib == false)
				g.drawString("Hetkel pole ühtegi funktsiooni", 20, 20);
			if (toimib == true) {
				int[][] a = new int[1001][10];
				int[][] b = new int[1001][10];
				int ct = 0;
				for (Funktsioon_Abi ketraja : funktsioonid) {
					int i = 0;
					double x, y;
					g.setColor(Color.BLACK);
					g.drawLine(w / 2+X_nihe, 0+Y_nihe-10000, w / 2+X_nihe, h+Y_nihe+10000);
					g.drawLine(0+X_nihe-10000, h / 2+Y_nihe, w+X_nihe+10000, h / 2+Y_nihe);

					double arv = -100.0 * suurus;
					for (int r = -94; r < 100; r += 1) {
						arv += 1. * suurus;
						g.drawLine(r * w / 10+X_nihe, h / 2 - h / 20+Y_nihe, r * w / 10+X_nihe, h
								/ 2 + h / 20+Y_nihe);
						if (arv != 0.0)
							g.drawString(String.valueOf(arv), r * w / 10 - 3+X_nihe, h
									/ 2 + h / 10+Y_nihe);
					}

					arv = -100.0 * suurus;
					for (int r = -94; r < 100; r += 1) {
						arv += 1. * suurus;
						g.drawLine(w / 2 - w / 30+X_nihe, h - (r * h / 10)+Y_nihe, w / 2 + w
								/ 30+X_nihe, h - (r * h / 10)+Y_nihe);
						if (arv != 0.0)
							g.drawString(String.valueOf(arv), w / 2 + w / 20+X_nihe, h
									- (r * h / 10) + 5+Y_nihe);
					}

					for (x = -50.0 * suurus; x < 50.0 * suurus; x += 0.1 * suurus) {
						y = ketraja.v22rtus(x);
						if (Double.isNaN(ketraja.v22rtus(x))) {
							a[i][ct] = -5555;
							b[i][ct] = -5555;
						}
						if (!Double.isNaN(ketraja.v22rtus(x))) {
							a[i][ct] = (int) ((x + (5. * suurus))
									/ (10. * suurus) * w);
							b[i][ct] = (int) (((5. * suurus) - y)
									/ (10. * suurus) * h);
						}
						i++;
					}
					g.setColor(v2rvid[ct]);
					String maiu = "y = " + sisendid.get(ct);
					g.drawString(maiu, 10, 10 + ct * 13);
					for (int j = 0; j < 999; j++) {
						if (a[j][ct] != -5555 && a[j + 1][ct] != -5555)
							g.drawLine(a[j][ct]+X_nihe, b[j][ct]+Y_nihe, a[j + 1][ct]+X_nihe,
									b[j + 1][ct]+Y_nihe);
					}
					ct++;
				}
				g.setColor(Color.BLUE);
				String X_komp = String
						.valueOf((double) ((int) (((double) (X_koord - w / 2-X_nihe))
								/ w * 10.0 * suurus * 100.0)) / 100.0);
				g.drawString("x = " + X_komp, X_koord + 5, Y_koord - 15);
				String Y_komp = String
						.valueOf((double) ((int) (((double) ((Y_koord - h / 2-Y_nihe) * (-1)))
								/ h * 10.0 * suurus * 100.0)) / 100.0);
				g.drawString("y = " + Y_komp, X_koord + 5, Y_koord - 5);

			}
		}

		public void actionPerformed(ActionEvent e) {
			sisend = vali.getText();
			if (sisendid.size() == 10) {
				tekst.setText("  Funktsioonide limiit (10) on täis saanud, rohkem funktsioone lisada ei saa.");
				return;
			}
			sisendid.add(sisend);
			tekst.setText("  Sisesta funktsioon ja vajuta enterit");
			try {
				mate = new Funktsioon_Abi(sisend);
				funktsioonid.add(mate);
			} catch (IllegalArgumentException evt) {
				tekst.setText(evt.getMessage() + "(" + sisend + ")");
				sisendid.remove(sisendid.size() - 1);
				repaint();
				return;
			}
			toimib = true;
			repaint();
			vali.selectAll();
			vali.requestFocus();

		}

	}
}
